﻿using System.Collections.Generic;
using System.Diagnostics;
using UltimatePlugin.Technicals;
using Zeta;
using Zeta.Common;
using Zeta.TreeSharp;

namespace UltimatePlugin.Db
{
    internal static class TreeHookManager
    {
        private static List<Composite> StandardCombatHook = new List<Composite>();
        private static List<Composite> StandardLootHook = new List<Composite>();
        private static List<Composite> StandardVendorRunHook = new List<Composite>();

        public static void ReplaceHook(bool install)
        {
            using (new PerformanceLogger(LogSeverity.Normal, "TreeHookManager.ReplaceHook"))
            {
                foreach (var hook in TreeHooks.Instance.Hooks)
                {
                    if (hook.Key == "Combat")
                    {
                        if (install)
                        {
                            foreach (Composite composite in hook.Value)
                            {
                                StandardCombatHook.Add(composite);
                            }
                            hook.Value.Clear();
                            hook.Value.Add(new Decorator(context => ActionHelper.CanCombatAction(context), CreateTargetAction()));
                        }
                        else
                        {
                            hook.Value.Clear();
                            foreach (Composite composite in StandardCombatHook)
                            {
                                hook.Value.Add(composite);
                            }
                        }
                    }
                    else if (hook.Key == "VendorRun")
                    {
                        if (install)
                        {
                            foreach (Composite composite in hook.Value)
                            {
                                StandardVendorRunHook.Add(composite);
                            }
                            hook.Value.Clear();
                            hook.Value.Add(new Decorator(context => ActionHelper.CanVendorRunAction(context), CreateVendorRunAction()));
                        }
                        else
                        {
                            hook.Value.Clear();
                            foreach (Composite composite in StandardVendorRunHook)
                            {
                                hook.Value.Add(composite);
                            }
                        }
                    }
                    else if (hook.Key == "Loot")
                    {
                        if (install)
                        {
                            foreach (Composite composite in hook.Value)
                            {
                                StandardLootHook.Add(composite);
                            } 
                            hook.Value.Clear();
                        }
                        else
                        {
                            hook.Value.Clear();
                            foreach (Composite composite in StandardLootHook)
                            {
                                hook.Value.Add(composite);
                            }
                        }
                    }
                }
            }
        }

        private static Composite CreateVendorRunAction()
        {
            return new PrioritySelector
                (
                    ((PrioritySelector)((Decorator)StandardVendorRunHook[0]).Children[0]).Children[0], // Copy Db Obscure action : Tp ? 
                    ((PrioritySelector)((Decorator)StandardVendorRunHook[0]).Children[0]).Children[1], // Copy Db Obscure action : Identify ? 
                    ((PrioritySelector)((Decorator)StandardVendorRunHook[0]).Children[0]).Children[2], // Copy Db Obscure action : ?????????
                    new Action(context => ActionHelper.DispatchItemAction(context)),
                    new Action(context => ActionHelper.StashAction(context)),
                    new Action(context => ActionHelper.SellAction(context)),
                    new Action(context => ActionHelper.SalvageAction(context)),
                    ((PrioritySelector)((Decorator)StandardVendorRunHook[0]).Children[0]).Children[7], // Copy Db Obscure action : Run to portal ? 
                    ((PrioritySelector)((Decorator)StandardVendorRunHook[0]).Children[0]).Children[8]  // Copy Db Obscure action : Tp ? 
                );
        }

        private static Composite CreateTargetAction()
        {
            return new PrioritySelector
                (
                    UltimateContextChangeHandler,
                    new Decorator(ret => ZetaDia.IsInGame && !ZetaDia.IsLoadingWorld && true, new Action(context => ActionHelper.TargetAction(context))),
                    new Decorator(ret => ZetaDia.IsInGame && !ZetaDia.IsLoadingWorld && false, new Action(context => ActionHelper.PausedAction(context)))
                );
        }

        private static object UltimateContextChangeHandler(object original)
        {
            Debug.WriteLine("UltimateContextChangeHandler : {0}", original);
            return original;
        }

        private static void DebugComposite(Composite composite)
        {
            Debug.Indent();
            if (composite == null)
            {
                Debug.WriteLine("Composite null");
            }
            else
            {
                Debug.WriteLine("Composite[{3}] {0} ({2}) : {1}", composite.Guid, composite.LastStatus, composite.IsRunning, composite.GetType().FullName);
                if (composite is GroupComposite)
                {
                    GroupComposite gc = (GroupComposite)composite;
                    foreach (Composite comp in gc.Children)
                    {
                        DebugComposite(comp);
                    }
                }
                else if (composite is Action)
                {
                    Action act = (Action)composite;
                    string tname = string.Empty;
                    string mname = string.Empty;
                    try
                    {
                        tname = act.Runner.Method.DeclaringType.FullName;
                        mname = act.Runner.Method.Name;
                    }
                    catch
                    {
                    }
                    Debug.WriteLine("Action {0} : {1}", tname, mname);
                }
                else if (composite is Sleep)
                {
                    Debug.WriteLine("Sleep");
                }
            }
            Debug.Unindent();
        }

        #region Hook Combat
        


        #endregion
    }
}
